/**
    atomic.c.tst - Unit tests for atomic primitives

    Copyright (c) All Rights Reserved. See details at the end of the file.
 */

/********************************** Includes **********************************/

#include    "testme.h"
#include    "mpr.h"

/*********************************** Locals ***********************************/

#define ATOMIC_COUNT    (2000)

static MprMutex atomicMutex;
static MprMutex *atomicLock = &atomicMutex;

/************************************ Code ************************************/

static int initAtomic()
{
    mprInitLock(atomicLock);
    return 0;
}


static void atomicAdd()
{
    static int  number = 0;
    int         before, i;

    for (i = 0; i < ATOMIC_COUNT; i++) {
        before = number;
        mprAtomicAdd(&number, 1);
        ttrue(number > before);
    }
}


static void atomicAdd64()
{
    static int64    number = 0;
    int64           before;
    int             i;

    for (i = 0; i < ATOMIC_COUNT; i++) {
        before = number;
        mprAtomicAdd64(&number, 1);
        ttrue(number > before);
    }
}


static void atomicCas()
{
    char     *ptr;
    char     *before;

    mprLock(atomicLock);

    /* Should succeed */
    ptr = 0;
    before = ptr;
    ttrue(mprAtomicCas((void**) &ptr, before, before + 1) == 1);
    ttrue(ptr == (void*) 1);

    /* Should fail */
    ptr = 0;
    before = (void*) 1;
    ttrue(mprAtomicCas((void**) &ptr, before, before + 1) == 0);
    ttrue(ptr == 0);
    mprUnlock(atomicLock);
}


int main(int argc, char **argv)
{
    mprCreate(argc, argv, 0);

    initAtomic();
    atomicAdd();
    atomicAdd64();
    atomicCas();
    return 0;
}


/*
    @copy   default

    Copyright (c) Embedthis Software. All Rights Reserved.

    This software is distributed under commercial and open source licenses.
    You may use the Embedthis Open Source license or you may acquire a 
    commercial license from Embedthis Software. You agree to be fully bound
    by the terms of either license. Consult the LICENSE.md distributed with
    this software for full details and other copyrights.

    Local variables:
    tab-width: 4
    c-basic-offset: 4
    End:
    vim: sw=4 ts=4 expandtab

    @end
 */
